﻿using BadOCR.Common;
using BadOCR.Runtime;
using BadOCR.View;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BadOCR.UserControls
{
    /// <summary>
    /// OCRUserControl.xaml 的交互逻辑
    /// </summary>
    public partial class OCRUserControl : UserControl
    {
        private bool _busy;

        public OCRUserControl()
        {
            InitializeComponent();
        }

        private async void button_screenshot_Click(object sender, RoutedEventArgs e)
        {
            var screentshotText = await OCRScreenshot();
            Text = screentshotText;

            if (UserConfig.Current.AutoSave)
                ClipboardHelper.SetText(screentshotText);
        }

        public string Text 
        {
            get => textbox_ocrresult.Text;

            set
            {
                textbox_ocrresult.Text = value;
            }
        }

        private void button_image_Click(object sender, RoutedEventArgs e)
        {
            OCRImageFile();
        }

        private void button_pdf_Click(object sender, RoutedEventArgs e)
        {
            // to do
        }

        private void button_merge_Click(object sender, RoutedEventArgs e)
        {
            // to do
        }

        private void button_copy_Click(object sender, RoutedEventArgs e)
        {
            Clipboard.SetText(textbox_ocrresult.Text);
        }

        private void button_setting_Click(object sender, RoutedEventArgs e)
        {
            UserConfigView.OpenWindow();
        }

        public async Task<string> OCRScreenshot()
        {
            if (_busy)
                return string.Empty;
            _busy = true;

            try
            {
                Application.Current.MainWindow.Visibility = Visibility.Hidden;
                await Task.Delay(200);                  // 窗口Visibility的变化需要一点时间, 这里等待窗口完全隐藏

                using (var screenImage = ScreenShotHelper.CaptureScreen())
                {
                    var overlay = new Overlay(screenImage);
                    overlay.ShowDialog();
                    if (overlay.CropImage == null)
                        return string.Empty;

                    using (var cropImage = overlay.CropImage)
                    {
                        var imageText = await GetImageText(cropImage);
                        return imageText?.Trim();
                    }
                }
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
            finally
            {
                Application.Current.MainWindow.Visibility = Visibility.Visible;
                SwitchToThisWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle, true);
                _busy = false;
            }
        }

        private async void OCRImageFile()
        {
            if (_busy)
                return;
            _busy = true;

            try
            {
                OpenFileDialog dialog = new OpenFileDialog();
                dialog.Title = "选择图片";
                dialog.Filter = "图片(*.jpg,*.jpeg,*.png,*.bmp)|*.jpg;*.jpeg;*.png;*.bmp";
                if (dialog.ShowDialog() == true)
                {
                    Application.Current.MainWindow.Visibility = Visibility.Hidden;
                    using (var image = System.Drawing.Image.FromFile(dialog.FileName))
                    {
                        var imageText = await GetImageText(image);
                        textbox_ocrresult.Text = imageText;
                    }
                }
            }
            catch (Exception ex)
            {
                textbox_ocrresult.Text = $"发生错误{ex.Message}";
            }
            finally
            {
                Application.Current.MainWindow.Visibility = Visibility.Visible;
                _busy = false;
            }
        }

        private async Task<string> GetImageText(System.Drawing.Image image)
        {
            var selectedEngineKind = UserConfig.Current.OCREngineKind;

            if (selectedEngineKind == OCREngineKind.Sougou)
            {
                return await Task.Run(() =>
                {
                    try
                    {
                        return new SougouOCR().General(image);
                    }
                    catch
                    {
                        // 这个接口偶尔会失败, 所以这里无脑重试一次
                        try
                        {
                            return new SougouOCR().General(image);
                        }
                        catch
                        {
                            return string.Empty;
                        }
                    }
                });
            }
            else if (selectedEngineKind == OCREngineKind.Baidu)
            {
                var cropImageBase64 = ImageProcess.ImageToBase64String(image);

                // 获取百度OCR配置信息
                var clientId = UserConfig.Current.ClientId;
                var clientSecret = UserConfig.Current.ClientSecret;

                return await Task.Run(() =>
                {
                    return new BaiduOCR(clientId, clientSecret).GeneralBasic(cropImageBase64, Overlay.LastLanguageType?.Value ?? LanguageKind.SimplifiedChinese);
                });
            }
            else if (selectedEngineKind == OCREngineKind.SpaceOCR)
            {
                var apiKey = "5a64d478-9c89-43d8-88e3-c65de9999580";

                using (var ms = new MemoryStream())
                {
                    image.Save(ms, ImageFormat.Png);
                    return await new SpaceOCR(apiKey).Generic(ms.ToArray(), Overlay.LastLanguageType?.Value ?? LanguageKind.SimplifiedChinese);
                }
            }
            else
            {
                return string.Empty;
            }
        }

        [DllImport("user32.dll", SetLastError = true)]
        static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
    }
}
